home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / misc / nnn.lha / nnn1.35 / src / NetBackProp.c < prev    next >
C/C++ Source or Header  |  1995-03-22  |  4KB  |  168 lines

  1. /*
  2.  *   $Id: NetBackProp.c 1.7 1995/03/21 10:51:08 projects Exp $
  3.  *
  4.  *    Function    NetBackProp
  5.  *     Programmer    Nicholas d'Alterio
  6.  *            Gideon Denby
  7.  *    Date        20/02/95
  8.  *
  9.  *  Synopsis:    This function carries out the back propagation algorithm
  10.  *        to ammend a set of weights in a neural network given a 
  11.  *        set of nodes which have been through a feed forwards stage.
  12.  *        It works with any network size.
  13.  *
  14.  *  NOTE    It assumes that the nodes are fully connected.
  15.  *
  16.  *  $Log: NetBackProp.c $
  17.  * Revision 1.7  1995/03/21  10:51:08  projects
  18.  * Small error in last change fixed
  19.  *
  20.  * Revision 1.6  1995/03/21  10:34:03  projects
  21.  * Made code for readable for loops
  22.  *
  23.  * Revision 1.5  1995/03/20  23:37:25  daltern
  24.  * Added gain factor
  25.  *
  26.  * Revision 1.4  1995/03/16  19:26:28  daltern
  27.  * Added code for momentum factor. Program now has an additional
  28.  * 3
  29.  * D array passed to it to store previous delta weights. If the
  30.  * momentum factor is 0 then it reverts to old behaviour
  31.  *
  32.  * Revision 1.3  1995/03/14  23:34:28  daltern
  33.  * Commented and cleaned up
  34.  *
  35.  * 
  36.  */
  37.  
  38. #include "Neural.h"
  39.  
  40. void NetBackProp( float ***Weight, float ***Delta_weight, float **Node, NET netI, 
  41.                          float *Output, float learn_rate, float mom_fac, float gain )
  42.  
  43.  {
  44.  
  45.   register int    s_node, e_node, layer;
  46.  
  47.   int        output_layer;
  48.  
  49.   int        nodes_on_layer;
  50.   int        nodes_on_next_layer;
  51.   int        nodes_on_prev_layer;
  52.  
  53.   float        delta;
  54.   float        upper_error;
  55.  
  56. /*
  57.  *  Loop from top of net down.
  58.  */
  59.  
  60.   output_layer = netI.NumLayers-1;
  61.  
  62.   for ( layer = output_layer; layer > 0; layer-- ) {
  63.  
  64.     nodes_on_layer      = netI.LayerSize[layer]+1;
  65.     nodes_on_prev_layer = netI.LayerSize[layer-1]+1;
  66.     nodes_on_next_layer = netI.LayerSize[layer+1]+1;
  67.  
  68. /*
  69.  *  Calculate all error terms for this layer. Put them in corresponding 
  70.  *  position in node array since its values are no longer needed.
  71.  */
  72.  
  73.     
  74. /*
  75.  *  Check if this is output layer and perform the appropriate error
  76.  *  calculation.
  77.  */
  78.  
  79.     if ( layer == output_layer ) {
  80.  
  81. /*
  82.  *  Error term for output layer.
  83.  */
  84.         
  85.         for ( e_node = 1; e_node < nodes_on_layer; e_node++ ) {        
  86.  
  87. /*
  88.  *  Calculate error term.
  89.  */
  90.             
  91.             delta = Node[layer][e_node] * gain *
  92.                 ( 1 - Node[layer][e_node] ) * 
  93.                                 ( Output[e_node-1] - Node[layer][e_node] );
  94.  
  95.             Node[layer][e_node] = delta;
  96.  
  97.         }   /* end for e_node */
  98.  
  99.     } else {
  100.  
  101. /*
  102.  *  Error term for Lower layers.
  103.  */
  104.  
  105.         for ( s_node = 0; s_node < nodes_on_layer; s_node++ ) {
  106.  
  107. /*
  108.  *  Sum the contribution from errors in the next layer up
  109.  */
  110.  
  111.             upper_error = 0.0;
  112.             for ( e_node = 1; e_node < nodes_on_next_layer; e_node++ ) {
  113.  
  114.                 upper_error += Node[layer+1][e_node] *
  115.                                                Weight[layer][s_node][e_node];
  116.  
  117.             }   /* end for e_node */
  118.  
  119. /*
  120.  *  Calculate error term.
  121.  */
  122.  
  123.             delta = Node[layer][s_node] * gain *
  124.                                 ( 1 - Node[layer][s_node] ) * upper_error;
  125.                 
  126.             Node[layer][s_node] = delta;
  127.  
  128.         }   /* end for s_node */
  129.  
  130.     }   /* end if : calc error depending on layer */
  131.  
  132. /*
  133.  *  Update all weights in this layer.
  134.  *  NOTE node[layer][e_node] is the stored delta term.
  135.  */
  136.  
  137. /*
  138.  *  Loop for each node on this layer.
  139.  */
  140.  
  141.     for ( e_node = 1; e_node < nodes_on_layer; e_node++ ) {
  142.  
  143. /*
  144.  *  Loop for each node connected to current node in this layer.
  145.  */
  146.  
  147.         for ( s_node = 0; s_node < nodes_on_prev_layer; s_node++ ) {
  148.  
  149.             Delta_weight[layer-1][s_node][e_node] = 
  150.                                  ( learn_rate *  Node[layer-1][s_node] * 
  151.                                                  Node[layer][e_node] ) +
  152.             (mom_fac * Delta_weight[layer-1][s_node][e_node]);
  153.  
  154.             Weight[layer-1][s_node][e_node] += Delta_weight[layer-1][s_node][e_node];
  155.  
  156.         }   /* end for s_node */
  157.  
  158.     }   /* end for e_node */
  159.  
  160.   }   /* end for layer */
  161.  
  162.   return;
  163.  
  164.  }   /* end function NetBackProp */
  165.  
  166.  
  167.  
  168.